#!/usr/bin/env python

#from Bowman, Samuel. 2011. Vowel Harmony, Opacity, and Finite-State OT. MA Thesis, The University of Chicago.
import sys, os, re, string
from optparse import OptionParser
sys.path[0:0] = 'src'
from pyphon import *
import pyphon_recurse, pyphon_maketableaux, pyphon_generate

usage = \
"""
pyphon_twotier.py modelfile inputfile

Performs two-tier OT evaluation: If an input file contains comma-separated input output pairs, then this finds intermediate forms and ERCs/rankings that can allow two-tier generation of those pairs. If only inputs are provided, a complete typology of outputs is provided.

The model filename must have no suffix, and must refer both to a model file (.mod), as built by pyphon_makemodel.py, and to a model description file (.csv).

Input forms with affixes must me marked as follows, with \. dividing affixes and \# delimiting the stem, as in:

a\.b\.c\#de\#f\.g

Output forms should be bare segments:

abcdejg

"""
	



def main(model, infilename):
	IO = True
	if ".csv" in infilename:
		infilename = infilename[:-4]

	log = open(model+"_twotier.csv",'w')
	log.write("input form, intermediate form, output form, erc for cyclic eval, erc for second eval\n")
	
	infile = open(infilename + ".csv", 'r')
	ios = []
	combinations = []
	con = []
	failed = []
	
	for line in infile: #read the input
		if (line and line[0] == "#") or len(line)<2:
			continue
		line = line.replace("\r","")
		line = line.replace("\n","")
		pair = line.rsplit(", ") #build pairs of input-output mappings (or input-blank mappings)
		if len(pair)>2:
			continue
		if len(pair)==1:
			IO = False
			pair.append("")
		print pair
		pair.extend([[],[],[],False, re.sub("(\\\#)|(\\\.)", "", pair[1])]) #checked, intermediates, interm ercs, locsat, target
		ios.append(pair)
		
	if not IO:
		print "Output forms not found. Generating typology."
	
	loutput = open("twotier_temp.csv",'w')
	for pair in ios:
		loutput.write(pair[0]+'\n') #write inputs for the first tier
	loutput.close()
	
	pyphon_recurse.main(model, "twotier_temp")	
	
	#scan the resulting typology
	infile = open(model + "_twotier_temp_recursive_typology.csv", 'r')
	
	loutput = open("twotier_temp.csv",'w')
	
	for line in infile: #take these as inputs for MakeTab
		line = line.replace("\r","")
		line = line.replace("\n","")
		if (line and line[0] == ",") or line=="Input, Output, ERCs, Intermediate Forms":
			continue
		print line
		sectioned = line.rsplit(', ')
				
		for pair in ios:		
			if sectioned[0] != pair[0]:
				continue
				
			pair[3].append(sectioned[1])
			pair[4].append(sectioned[2])		
				
			#produce input line
			loutput.write(sectioned[1]+'\n')
		
	loutput.close()
	infile.close()
	
	pyphon_maketableaux.main(model, "twotier_temp", "ot", "twotier_tab_temp")
	
	#Read tableau
	infile = open("twotier_tab_temp.csv", 'r')
		
	for line in infile: #take these as inputs for MakeTab
		line = line.replace("\r","")
		line = line.replace("\n","")		
		if (con == [] and ",,," in line):
			sectioned = line.rsplit(',')
			con = sectioned[3:]
			continue
		if(line and line[0]==","):
			continue
		
	print "Twotier Read CON:", con
	
	infile.close()
		
	pyphon_generate.main("twotier_tab_temp.csv", "twotier_temp", "ot")
	
	infile = open("twotier_temp.csv", 'r')
		
	for line in infile: #scan the intermediate-final form pairs
		line = line.replace("\r","")
		line = line.replace("\n","")
		if(line and line[0]=="/"):
			seg = line.rsplit(",")
			n = re.search('(?<=/).*(?=/)', seg[0])
			input = n.group(0)
			n = re.search('(?<=\[).*(?=\])', seg[1])			
			output = re.sub("(#)|(\.)", "", n.group(0))
	
	
	
			if len(seg)>len(con)+2:
				ercs = ",".join(seg[(len(con)+1):])
				localercs=[]
				for n in re.finditer('[wel]+', ercs):
					localercs.append(n.group(0))
				localerc = "_".join(localercs)
			else:
				localerc = 'e'*len(con)
				
			for pair in ios:
				if IO and pair[6]==output and [input, output] not in pair[2]:
					pair[2].append([input, output])
					found = False
					for i in range(len(pair[3])):
						if input == pair[3][i]:
							initialerc = pair[4][i]
							if initialerc == '0':
								initialerc = 'e'*len(con)
							found = True
							break
					if not found:
						continue
							
					#Found an I-I-O mapping!
					pair[5] = True
					#print "Found",pair[0], input, output,initialerc,localerc,"\n"
					log.write(pair[0]+","+input+","+output+","+initialerc+","+localerc+'\n')
					combinations.append([pair[0], pair[6], output, initialerc, localerc])
				
				if not IO and [input, output] not in pair[2]:
					pair[2].append([input, output])
					found = False
					for i in range(len(pair[3])):
						if input == pair[3][i]:
							initialerc = pair[4][i]
							if initialerc == '0':
								initialerc = 'e'*len(con)
							found = True
							break
					if not found:
						continue
							
					#Found an I-I-O mapping!
					pair[5] = True
					#print "Found",pair[0], input, output,initialerc,localerc,"\n"
					log.write(pair[0]+","+input+","+output+","+initialerc+","+localerc+'\n')
					combinations.append([pair[0], pair[6], output, initialerc, localerc])
	
	for pair in ios:	
		if not pair[5]:
			failed.append(pair)
		
	infile.close()
	
	log.close()
	
	if failed==[]: #If we have a complete set, send it to the language-finder
		twotierlangs.find2tlangs(model+"_twotier.csv")
		print "I-I-O sets written to "+model+"_twotier.csv"
		print "Language definitions written to "+model+"_twotier_languages.csv"
	else:
		print "Some IO pairs could not be generated:", failed

	os.remove('twotier_temp.csv')
	os.remove('twotier_tab_temp.csv')
	os.remove(model + "_twotier_temp_recursive_typology.csv")



if __name__ == "__main__":
    parser = OptionParser(usage=usage)
    parser.add_option('-V', '--version', action='store_true', dest='version',
            default=False,
            help='Print pyPhon version and quit.')
    p_options, args = parser.parse_args()

    if p_options.version:
        print 'pyPhon version %s.' % pyphon.__version__
        raise SystemExit

    if len(args) < 2:
    	print usage
    elif len(args) < 3:
        main(args[0], args[1])
    else:
        print usage

